package com.kevin.netty.starter.preperties;

import com.kevin.netty.starter.enums.ProtocolEnum;
import io.netty.handler.logging.LogLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Objects;

@Getter
@Setter
@ToString
@Accessors(chain = true)
@Component
@ConfigurationProperties(prefix = "netty.servers")
public class ServerProperties {

    /**
     * 协议枚举
     */
    private ProtocolEnum protocol;
    /**
     * Netty 服务的日志级别，不是 spring-boot 服务
     */
    private LogLevel logLevel;
    /**
     * 名称
     */
    private String name;
    /**
     * 绑定地址
     */
    private String host;
    /**
     * 绑定端口
     */
    private Integer port;
    /**
     * 服务线程数
     */
    private Integer bossCount;
    /**
     * 工作线程数
     */
    private Integer workerCount;
    /**
     * 读超时时间
     */
    private Integer readerIdleTime;
    /**
     * 写超时时间
     */
    private Integer writerIdleTime;
    /**
     * 读、写超时时间
     */
    private Integer allIdleTime;

    /**
     * 低水位
     */
    private String lowWaterMark;

    /**
     * 高水位
     */
    private String highWaterMark;

    /**
     * 发送缓冲区
     */
    private String sndBuf;

    /**
     * 接收缓冲区
     */
    private String rcvBuf;

    /**
     * SSL/TLS 双向认证配置
     */
    private SslProperties ssl = new SslProperties();

    public LogLevel getLogLevel() {
        return Objects.isNull(this.logLevel) ? LogLevel.INFO : this.logLevel;
    }

    public Long getLowWaterMark() {
        this.lowWaterMark = StringUtils.hasText(this.lowWaterMark) ? this.lowWaterMark : "1";
        return formatSize(this.lowWaterMark);
    }

    public Long getHighWaterMark() {
        this.highWaterMark = StringUtils.hasText(this.highWaterMark) ? this.highWaterMark : "2MB";
        return formatSize(this.highWaterMark);
    }

    public Long getSndBuf() {
        this.sndBuf = StringUtils.hasText(this.sndBuf) ? this.sndBuf : "4MB";
        return formatSize(this.sndBuf);
    }

    public Long getRcvBuf() {
        this.rcvBuf = StringUtils.hasText(this.rcvBuf) ? this.rcvBuf : "4MB";
        return formatSize(this.rcvBuf);
    }

    public static Long formatSize(String sizeStr) {
        long size = 0L;
        if (!StringUtils.hasText(sizeStr)) {
            return size;
        }
        if (sizeStr.endsWith("KB")) {
            size = 1024 * subString(sizeStr);
        } else if (sizeStr.endsWith("MB")) {
            size = 1024 * 1024 * subString(sizeStr);
        } else if (sizeStr.endsWith("GB")) {
            size = 1024 * 1024 * 1024 * subString(sizeStr);
        } else {
            size = Long.parseLong(sizeStr);
        }
        return size;
    }

    private static Long subString(String sizeStr) {
        return Long.parseLong(sizeStr.substring(0, sizeStr.length() - 2).trim());
    }

}
